package persistent.prestige.platform.base.utils;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Properties;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * 读取系统配置文件中值 (*.properties)
 * 
 * @author prestigeding
 * 
 */
public class PropertyHolder {
	
	public static final String CONFIG_FILE_NAME = "application.properties";

	private static Properties properties;

	private static Object lock = new Object();

	private PropertyHolder() {
	}

	private static final Logger logger = LoggerFactory.getLogger(PropertyHolder.class);

	public static final void initialize() {
		logger.info("PropertyUtils initialize....");
		if (properties == null) {
			synchronized (lock) {
				if (properties != null)
					return;

				properties = new Properties();

				ClassLoader classLoader = Thread.currentThread()
						.getContextClassLoader();
				loadProperties(classLoader, CONFIG_FILE_NAME);

			}
		}

	}
	

	/**
	 * 加载资源
	 * 
	 * @param classLoader
	 * @param fileName
	 */
	private static final void loadProperties(ClassLoader classLoader,
			String fileName) {
		InputStream ins = null;
		try {
			ins = classLoader.getResourceAsStream(fileName);
			properties.load(ins);
			ins.close();
			ins = null;

			logger.info("成功从classpath加载:{}", fileName);
		} catch (Exception e) {
			logger.error("加载资源文件{}失败", fileName, e);
			if (ins == null) {
				try {
					ins.close();
					ins = null;
				} catch (IOException e1) {
					ins = null;
				}
			}
		}
	}

	/**
	 * 取出Property，但以System的Property优先.
	 */
	private static String getValue(String key) {
		String systemProperty = System.getProperty(key);
		if (systemProperty != null) {
			return systemProperty;
		}
		return properties.getProperty(key);
	}

	/**
	 * 取出String类型的Property，但以System的Property优先,如果都為Null则抛出异常.
	 */
	public static String getProperty(String key) {
		String value = getValue(key);
		if (value == null) {
			throw new NoSuchElementException();
		}
		return value;
	}

	/**
	 * 取出String类型的Property，但以System的Property优先.如果都為Null則返回Default值.
	 */
	public static String getProperty(String key, String defaultValue) {
		String value = getValue(key);
		return value != null ? value : defaultValue;
	}

	/**
	 * 取出Integer类型的Property，但以System的Property优先.如果都為Null或内容错误则抛出异常.
	 */
	public static Integer getInteger(String key) {
		String value = getValue(key);
		if (value == null) {
			throw new NoSuchElementException();
		}
		return Integer.valueOf(value);
	}

	/**
	 * 取出Integer类型的Property，但以System的Property优先.如果都為Null則返回Default值，如果内容错误则抛出异常
	 */
	public static Integer getInteger(String key, Integer defaultValue) {
		String value = getValue(key);
		return value != null ? Integer.valueOf(value) : defaultValue;
	}

	public static final Long getLong(String key) {
		String value = getValue(key);
		if (StringUtils.isEmpty(value))
			return 0L;
		return Long.parseLong(value);
	}

	public static final Long getLong(String key, Long defaultValue) {
		String value = getValue(key);
		return value != null ? Long.valueOf(value) : defaultValue;
	}

	/**
	 * 取出Double类型的Property，但以System的Property优先.如果都為Null或内容错误则抛出异常.
	 */
	public static Double getDouble(String key) {
		String value = getValue(key);
		if (value == null) {
			throw new NoSuchElementException();
		}
		return Double.valueOf(value);
	}

	/**
	 * 取出Double类型的Property，但以System的Property优先.如果都為Null則返回Default值，如果内容错误则抛出异常
	 */
	public static Double getDouble(String key, Integer defaultValue) {
		String value = getValue(key);
		return value != null ? Double.valueOf(value) : defaultValue;
	}

	/**
	 * 取出Boolean类型的Property，但以System的Property优先.如果都為Null抛出异常,如果内容不是true/
	 * false则返回false.
	 */
	public static Boolean getBoolean(String key) {
		String value = getValue(key);
		if (value == null) {
			throw new NoSuchElementException();
		}
		return Boolean.valueOf(value);
	}

	/**
	 * 取出Boolean类型的Property，但以System的Property优先.如果都為Null則返回Default值,如果内容不为true/
	 * false则返回false.
	 */
	public static Boolean getBoolean(String key, boolean defaultValue) {
		String value = getValue(key);
		return value != null ? Boolean.valueOf(value) : defaultValue;
	}

}
